#ifndef __IPS_H__
#define __IPS_H__

#include <global/header/lock.h>
#include "proc.h"

/* Assume that the event pointer is 4-aligned */
/* NEAR-STANDARD SYNC INTERFACE */
typedef volatile struct ips_node_s ips_node_t;

struct ips_node_s
{
	 struct
	 {
		  unsigned int wait    : 1;
		  unsigned int ac_wait : 1;
		  unsigned int event   : 30;
	 } __attribute__ ((packed));
	 ips_node_t *prev, *next;
} __attribute__((aligned (4)));

struct mutex_s
{
	 spin_lock_t lock;
	 struct
	 {
		  unsigned int hold : 1;
		  unsigned int wait : 1;
		  unsigned int head : 30;
	 } __attribute__((packed));
} __attribute__ ((aligned (4)));

typedef volatile struct mutex_s mutex_t;

struct semaphore_s
{
	 spin_lock_t lock;
	 uint32_t    count;
	 struct
	 {
		  unsigned int wait  : 1;
		  unsigned int head  : 30;
	 } __attribute__((packed));
} __attribute__ ((aligned (4)));
typedef volatile struct semaphore_s semaphore_t;

struct bqueue_s
{
	 spin_lock_t lock;
	 struct
	 {
		  unsigned int wait  : 2;
		  unsigned int head  : 30;
	 } __attribute__((packed));
} __attribute__ ((aligned (4)));
typedef volatile struct bqueue_s bqueue_t;

int  ips_is_finish(ips_node_t *node);
void ips_wait(ips_node_t *node);
/* 0 for break/success, 1 for wait(again) */
int  ips_wait_try(ips_node_t *node);

void mutex_init(mutex_t *mutex);
int  mutex_try_acquire(mutex_t *mutex);
int  mutex_acquire(mutex_t *mutex, ips_node_t *node, proc_event_t event);
void mutex_ac_break(mutex_t *mutex, ips_node_t *node);
void mutex_release(mutex_t *mutex);

void semaphore_init(semaphore_t *sem, uint32_t count);
int  semaphore_try_acquire(semaphore_t *sem);
int  semaphore_acquire(semaphore_t *sem, ips_node_t *node, proc_event_t event);
void semaphore_ac_break(semaphore_t *sem, ips_node_t *node);
/* 1 for notify, 0 for no notify */
int  semaphore_release(semaphore_t *sem);

void bqueue_init(bqueue_t *bq);
int  bqueue_put(bqueue_t *bq, ips_node_t *node, proc_event_t event);
int  bqueue_get(bqueue_t *bq, ips_node_t *node, proc_event_t event);

#endif
